#include "qmlcppinterface.h"

QmlCppInterface::QmlCppInterface(QObject *parent) :
    QObject(parent),
    m_socket(0),
    m_server(0),
    m_msgSize(0)
{
}

void QmlCppInterface::connect(const QString &addr)
{
    qDebug() << "QmlCppInterface::connect()";
    if (m_socket) {
        delete m_socket;
        m_socket = NULL;
    }
    m_socket = new QTcpSocket(this);
    QObject::connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)),
                    this, SLOT(connError(QAbstractSocket::SocketError)));
    QObject::connect(m_socket, SIGNAL(connected()),
                     this, SLOT(connEstabilished()));
    m_socket->connectToHost(addr, 5440);
}

void QmlCppInterface::connError(QAbstractSocket::SocketError errorType)
{
    qDebug() << "Error while connecting to peer." << errorType;
    startServer();
}

void QmlCppInterface::connEstabilished()
{
    qDebug() << "Connection estabilished.";
    emit connected();
    QObject::connect(m_socket, SIGNAL(readyRead()),
                     this, SLOT(blockReceived()));
    QObject::connect(m_socket, SIGNAL(disconnected()),
                     this, SLOT(disconnectedSlot()));
}

void QmlCppInterface::newConnectionSlot()
{
    qDebug() << "In newConnectionSlot()";
    if (m_socket) {
        delete m_socket;
    }
    m_socket = m_server->nextPendingConnection();
    connEstabilished();
}

void QmlCppInterface::sendMsg(const QString& msg)
{
    qDebug() << "In sendMsg";
    if (m_socket && (m_socket->state() == QAbstractSocket::ConnectedState)) {
        qDebug() << "going to send.";
        QByteArray ba;
        QDataStream out(&ba, QIODevice::WriteOnly);
        out << (quint16)msg.size(); //Tamanho da mensagem.
        out << msg;
        m_socket->write(ba);
    }
}

void QmlCppInterface::disconnect()
{
    qDebug() << "in QmlCppInterface::disconnect() slot";
    if (m_server && m_server->isListening()) {
        qDebug() << "in QmlCppInterface::disconnect() : closing server.";
        m_server->close();
        emit disconnected();
    }
    if (m_socket) {
        qDebug() << "in QmlCppInterface::disconnect() : disconnecting socket.";
        m_socket->disconnectFromHost();
    }
    //emit disconnected();
}

void QmlCppInterface::blockReceived()
{
    QDataStream in(m_socket);
    if (!m_msgSize) {
        if (m_socket->bytesAvailable() >= (int)sizeof(qint16) ) {
            in >> m_msgSize;
        }
    }

    if (m_msgSize && m_socket->bytesAvailable() > m_msgSize) {
        QString receivedMsg;
        in >> receivedMsg;
        m_msgSize = 0;
        emit msgReceived(QVariant("\n" + receivedMsg));
    }
}

void QmlCppInterface::disconnectedSlot()
{
   qDebug() << "in QmlCppInterface::disconnectedSlot()";
   if (m_server) {
       m_server->close();
   }
   emit disconnected();
}

void QmlCppInterface::startServer()
{
    qDebug() << "in QmlCppInterface::startServer()";
   if (!m_server) {
       m_server = new QTcpServer(this);
       QObject::connect(m_server, SIGNAL(newConnection()),
                        this, SLOT(newConnectionSlot()));
   }
   m_server->listen(QHostAddress::Any, 5440);
   emit waitingForConnection();
}
